package managers.conversationManager.services;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ResourceBundle;

import managers.conversationManager.ConversationManager;
import managers.conversationManager.DefaultTCPSocket;
import managers.conversationManager.GenericSocket;
import managers.conversationManager.OfflineConversation;
import managers.conversationManager.OnlineConversation;
import managers.messengerManager.MessengerManager;
import managers.messengerManager.services.Service;
import spotGUI.floatingChatGUI.FloatingChat;
import utils.ManagingMessage;
import utils.ManagingMessage.Type;
import utils.StackTracePrinter;
import utils.UserData;

public class ContactUserService extends Service {

	private MessengerManager manager = MessengerManager.getSharedInstance();
	private int userId;
	private int baseWaitTime;
	private UserData requestedUserData;	
	private FloatingChat chat;
			
	public ContactUserService(int userId, FloatingChat chat) {
		this(userId, DEFAULT_BASE_WAIT_TIME, chat);
	}

	public ContactUserService(int userId, int baseWaitTime, FloatingChat chat) {
		super ("Contact User");
		this.userId = userId;
		this.baseWaitTime = baseWaitTime;
		this.chat = chat;
	}


	
	public void run() {
		try {
			if (requestUserData()) {
				requestedUserData = (UserData) externalObject;
				chat.updateStatus(ResourceBundle.getBundle("managers.conversationManager.services.messages").getString("m.1"), FloatingChat.WORKING_ICON);
				manager.getDataManager().getUsers().put((Integer) requestedUserData.getProperty("id"), requestedUserData);
				if ((Boolean) requestedUserData.getProperty("online")) {
					contactUser(requestedUserData);
				} else
					chat.setConversation(new OfflineConversation(userId));
			} else {
				chat.setEnabled(false);
				chat.updateStatus(ResourceBundle.getBundle("managers.conversationManager.services.messages").getString("m.2"), FloatingChat.ERROR_ICON);
			}
		} catch (Exception e) {
			chat.setEnabled(false);
			StackTracePrinter.print(e);
			chat.updateStatus(ResourceBundle.getBundle("managers.conversationManager.services.messages").getString("m.3"), FloatingChat.ERROR_ICON);
		}
		ConversationManager.getSharedInstance().getUserRequestsManager().removePendingConnection(userId);
	}



	public void contactUser (UserData user) throws IOException {

		GenericSocket socket = new DefaultTCPSocket(new Socket((InetAddress) user.getProperty("ipAddress"), (Integer) user.getProperty("conversationPort")));
		ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
		//send the UserData.
		oos.writeObject((manager.getDataManager().getUsers().get(MessengerManager.getSharedInstance().getUserId())));
		chat.setConversation(new OnlineConversation (userId, socket));
	}


	public synchronized boolean requestUserData () throws Exception {
		ManagingMessage request = new ManagingMessage(Type.USER_DATA_REQUEST);
		request.putProperty("requestedUserId", userId);
		manager.getSingleProtocol().send(request, manager.getServerAddress(), manager.getServerPort());

		wait(baseWaitTime*2);

		if (externalObject == null)
			return false;
		return true;
	}

}
